package com.autumn.sms.service.services.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.autumn.application.dto.PageQueryResult;
import com.autumn.application.dto.input.DefaultPrimaryKeyInput;
import com.autumn.application.dto.input.PageQueryInput;
import com.autumn.application.dto.input.QueryCriteriaItemInput;
import com.autumn.mybatis.criterion.IQuerySection;
import com.autumn.mybatis.criterion.ISpecifyUpdateSection;
import com.autumn.mybatis.criterion.Query;
import com.autumn.mybatis.criterion.SpecifyUpdate;
import com.autumn.sms.service.consts.ServiceConsts;
import com.autumn.sms.service.entities.PlatformInfo;
import com.autumn.sms.service.entities.PlatformTemplate;
import com.autumn.sms.service.entities.SmsAppInfo;
import com.autumn.sms.service.repositories.IPlatformInfoRepository;
import com.autumn.sms.service.repositories.IPlatformTemplateParameterRepository;
import com.autumn.sms.service.repositories.IPlatformTemplateRepository;
import com.autumn.sms.service.repositories.ISmsAppTemplatePlatformRepository;
import com.autumn.sms.service.services.ICacheService;
import com.autumn.sms.service.services.IPlatformInfoService;
import com.autumn.sms.service.services.dto.input.PlatformInfoInput;
import com.autumn.sms.service.services.dto.input.PlatformInfoUpdateInput;
import com.autumn.sms.service.services.dto.output.PlatformInfoOutput;
import com.autumn.sms.service.utils.AuditUtils;
import com.autumn.util.AutoMapUtils;
import com.autumn.util.DataRollbackException;
import com.autumn.validation.ValidationException;

/**
 * 平台信息服务
 * 
 * @author JuWa ▪ Zhang
 * @date 2018年1月13日
 * @since jdk 1.8
 */
@Service
public class PlatformInfoServiceImpl extends AbstractBasicService<IPlatformInfoRepository, PlatformInfo>
		implements IPlatformInfoService {

	@Autowired
	private ICacheService cacheService;
	@Autowired
	private IPlatformInfoRepository platformRepo;

	@Autowired
	private IPlatformTemplateRepository platformTemplaeRepo;

	@Autowired
	private IPlatformTemplateParameterRepository platformTemplateParamRepo;

	@Autowired
	private ISmsAppTemplatePlatformRepository appTemplatePlatformRepo;

	@Override
	public PlatformInfoOutput add(PlatformInfoInput input) {
		PlatformInfo first;
		// 检测是否有平台的code字段重复
		checkIsDuplicateCode(input.getCode());
		first = AutoMapUtils.mapTo(PlatformInfo.class, input);
		first.insertAuditingInitialize();
		// 新增应用设置为草稿状态
		first.setStatus(ServiceConsts.Status.STATUS_DRAFT);
		platformRepo.insert(first);
		return AutoMapUtils.mapTo(PlatformInfoOutput.class, first);
	}

	/**
	 * 检测是否有平台的code字段重复
	 * 
	 * @param code
	 */
	private void checkIsDuplicateCode(String code) {
		Query query = new Query(PlatformInfo.class);
		AuditUtils.filterDelete(query);
		query.eq("code", code);
		PlatformInfo first = platformRepo.selectFirst(query.builderSection());
		if (first != null) {
			throw new ValidationException(String.format("code为 [%s] 平台记录已经存在", code));
		}
	}

	@Override
	public PlatformInfoOutput modify(PlatformInfoInput input) {
		PlatformInfoUpdateInput updateInput = (PlatformInfoUpdateInput) input;
		PlatformInfo platformInfo = checkIsExistEntityByPrimaryId(updateInput.getId());
		if (platformInfo.getStatus() == ServiceConsts.Status.STATUS_RELEASE) {
			throw new ValidationException("发布状态的平台不能修改");
		}
		if (!input.getCode().equals(platformInfo.getCode())) {
			checkIsDuplicateCode(input.getCode());
		}
		AutoMapUtils.map(input, platformInfo);
		platformInfo.setStatus(ServiceConsts.Status.STATUS_DRAFT);
		platformInfo.updateAuditing();
		platformRepo.update(platformInfo);
		return AutoMapUtils.mapTo(PlatformInfoOutput.class, platformInfo);
	}

	@Override
	@Transactional(rollbackFor = DataRollbackException.class)
	public void delete(DefaultPrimaryKeyInput input) {
		PlatformInfo platformInfo = checkIsExistEntityByPrimaryId(input.getId());
		if (platformInfo.getStatus() == ServiceConsts.Status.STATUS_RELEASE) {
			throw new ValidationException("发布状态的平台不能删除");
		}
		ISpecifyUpdateSection section = AuditUtils.softDeleteById(PlatformInfo.class, input.getId());
		platformRepo.updateBySpecify(section);
		// 删除该平台下的platform_template,
		SpecifyUpdate update = new SpecifyUpdate(PlatformTemplate.class);
		update.set("isDelete", true).set("gmtDelete", new Date()).eq("platformId", input.getId());
		platformTemplaeRepo.updateBySpecify(update.builderSection());
		// 删除该平台下的platform_template_parameter
		platformTemplateParamRepo.deleteByPlatformId(input.getId());
		// 删除该平台下的对应应用的平台模板, app_template_platform
		appTemplatePlatformRepo.deleteByPlatformId(input.getId());

	}

	@Override
	public PlatformInfoOutput get(DefaultPrimaryKeyInput input) {
		PlatformInfo platformInfo = checkIsExistEntityByPrimaryId(input.getId());
		return AutoMapUtils.mapTo(PlatformInfoOutput.class, platformInfo);
	}

	@Override
	protected IPlatformInfoRepository getRepository() {
		return platformRepo;
	}

	@Override
	protected Class<PlatformInfo> getEntityClass() {
		return PlatformInfo.class;
	}

	@Override
	public void release(DefaultPrimaryKeyInput input) {
		PlatformInfo platformInfo = checkIsExistEntityByPrimaryId(input.getId());
		if (platformInfo.getStatus() == ServiceConsts.Status.STATUS_RELEASE) {
			throw new ValidationException(String.format("平台信息表中主键ID为 [%s] 的记录已发布", input.getId()));
		}
		platformInfo.updateAuditing();
		platformInfo.setStatus(ServiceConsts.Status.STATUS_RELEASE);
		platformRepo.update(platformInfo);
	}

	@Override
	@Transactional(rollbackFor = DataRollbackException.class)
	public void disable(DefaultPrimaryKeyInput input) {
		PlatformInfo platformInfo = checkIsExistEntityByPrimaryId(input.getId());
		if (platformInfo.getStatus() == ServiceConsts.Status.STATUS_DISABLE) {
			throw new ValidationException(String.format("平台信息表中主键ID为 [%s] 的记录已停用", input.getId()));
		}
		platformInfo.updateAuditing();
		platformInfo.setStatus(ServiceConsts.Status.STATUS_DISABLE);
		platformRepo.update(platformInfo);
		// 停用平台，该平台下的平台模板也要停用
		SpecifyUpdate update = new SpecifyUpdate(PlatformTemplate.class);
		update.set("status", ServiceConsts.Status.STATUS_DISABLE).set("gmtModified", new Date())
				.eq("platformId", platformInfo.getId()).eq("isDelete", false);
		platformTemplaeRepo.updateBySpecify(update.builderSection());

		// 刷新redis缓存
		cacheService.removeAllSendTemplate();
	}

	@Override
	public List<PlatformInfoOutput> list() {
		Query query = new Query(PlatformInfo.class);
		query.eq("isDelete", false);
		List<PlatformInfo> selectAll = this.platformRepo.selectList(query.builderSection());
		return  AutoMapUtils.mapList(selectAll, PlatformInfoOutput.class);
	}
	
	@Override
	public PageQueryResult<PlatformInfoOutput> pageQuery(PageQueryInput input) {
		Query query = new Query(SmsAppInfo.class);
		List<QueryCriteriaItemInput> criterias = input.getCriterias();
		if (criterias != null && criterias.size() > 0) {
			query.criteria(criterias);
		}
		Integer maxValue = getPageMaxValue();
		if (input.getPageSize() > maxValue) {
			input.setPageSize(maxValue);
		}
		 query.eq("isDelete", false);
		IQuerySection section = query.builderSection();
		int count = platformRepo.countByWhere(section);
		PageQueryResult<PlatformInfoOutput> result = new PageQueryResult<PlatformInfoOutput>(
				input.getCurrentPage(), input.getPageSize(), count);
		if (count > 0) {
			query.page(result.getCurrentPage(), result.getPageSize());
			List<PlatformInfo> selectList = platformRepo.selectList(query.builderSection());
			result.setItems(AutoMapUtils.mapList(selectList, PlatformInfoOutput.class));
		}
		return result;
	}

}
